package controllers

import (
	"Article-Manage/models"
	"bytes"
	"encoding/gob"
	"math"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
)

type ArticleController struct {
	BaseController
}

func (c *ArticleController) GetArticles() {
	userName := c.GetSession("userName")
	if userName == nil {
		c.Redirect("/login", 302)
		return
	}

	var articles []models.Article
	typeName := c.GetString("select")
	qs := orm.NewOrm().QueryTable("article").RelatedSel("ArticleType")
	if typeName != "" {
		qs = qs.Filter("ArticleType__TypeName", typeName)
	}
	count, _ := qs.Count()

	var types []models.ArticleType
	conn, err := redis.Dial("tcp", "47.111.181.52:6379")
	if err == nil {
		defer conn.Close()
	}
	rep, err := conn.Do("get", "types")

	if rep == nil {
		beego.Info("Redis无数据")
		orm.NewOrm().QueryTable("ArticleType").All(&types)

		var buffer bytes.Buffer
		enc := gob.NewEncoder(&buffer) // 获取编码器
		enc.Encode(&types)             //编码
		conn.Do("set", "types", buffer.Bytes())
	} else {
		beego.Info("Redis有数据")
		data, _ := redis.Bytes(rep, err)
		dec := gob.NewDecoder(bytes.NewReader(data))
		dec.Decode(&types)
	}

	page, _ := c.GetInt("page", 1)
	pageSize := 3
	pageCount := math.Ceil(float64(count) / float64(pageSize))

	qs.Limit(pageSize, pageSize*(page-1)).All(&articles)

	c.Data["types"] = types
	c.Data["typeName"] = typeName
	c.Data["count"] = count
	c.Data["articles"] = articles
	c.Data["page"] = page
	c.Data["pageCount"] = int(pageCount)
	c.TplName = "index.html"
	c.Layout = "layout.html"
}

func (c *ArticleController) GetArticle() {
	var types []models.ArticleType
	orm.NewOrm().QueryTable("ArticleType").All(&types)
	c.Data["types"] = types
	c.TplName = "add.html"
	c.Layout = "layout.html"
}

func (c *ArticleController) PostArticle() {
	c.TplName = "add.html"
	c.Layout = "layout.html"
	articleName := c.GetString("articleName")
	typeName := c.GetString("select")
	content := c.GetString("content")

	if articleName == "" || content == "" {
		c.Data["errmsg"] = "添加数据不完整"
		return
	}

	var articleType = models.ArticleType{TypeName: typeName}
	orm.NewOrm().Read(&articleType, "TypeName")

	filePath := c.UploadFile("uploadname")

	article := models.Article{
		ArtiName:    articleName,
		Acontent:    content,
		Aimg:        filePath,
		ArticleType: &articleType,
	}

	orm.NewOrm().Insert(&article)
	c.Redirect("/articles", 302)
}

func (c *ArticleController) GetArticleDetail() {
	c.TplName = "content.html"
	c.Layout = "layout.html"

	id, err := c.GetInt("id")
	if err != nil {
		beego.Info("传递的链接错误")
	}
	article := models.Article{Id: id}
	o := orm.NewOrm()
	o.Read(&article)
	o.LoadRelated(&article, "ArticleType")
	article.Acount += 1

	m2m := o.QueryM2M(&article, "Users")
	userName := c.GetSession("userName")
	if userName == nil {
		c.Redirect("/login", 302)
		return
	}

	// m2m insert
	user := models.User{
		Name: userName.(string)}
	o.Read(&user, "Name")
	o.LoadRelated(&article, "Users")
	if len(article.Users) > 0 {
		for _, v := range article.Users {
			if user.Name != v.Name {
				m2m.Add(user)
			}
		}
	} else {
		m2m.Add(user)
	}

	// m2m read
	o.LoadRelated(&article, "Users")
	o.Update(&article)
	c.Data["article"] = article
}

func (c *ArticleController) GetArticleEdit() {
	c.TplName = "update.html"
	c.Layout = "layout.html"

	id, err := c.GetInt("id")
	if err != nil {
		beego.Info("传递的链接错误")
	}
	article := models.Article{Id: id}
	o := orm.NewOrm()
	o.Read(&article)

	c.Data["article"] = article
}

func (c *ArticleController) PostArticleEdit() {
	id, err := c.GetInt("id")
	articleName := c.GetString("articleName")
	content := c.GetString("content")

	filePath := c.UploadFile("uploadname")

	if err != nil || articleName == "" || content == "" || filePath == "" {
		beego.Info("请求错误")
		return
	}

	o := orm.NewOrm()
	article := models.Article{
		Id: id,
	}

	if err = o.Read(&article); err != nil {
		beego.Info("更新的文章不存在")
		return
	}
	article.ArtiName = articleName
	article.Acontent = content
	if filePath != "no_img" {
		article.Aimg = filePath
	}

	beego.Info(article)
	o.Update(&article)

	c.Redirect("/articles", 302)
}

func (c *ArticleController) DeleteArticle() {
	id, err := c.GetInt("id")
	if err != nil {
		beego.Info("删除文章请求路径错误")
		return
	}
	o := orm.NewOrm()
	var article models.Article
	article.Id = id
	o.Delete(&article)
	c.Redirect("/articles", 302)
}

func (c *ArticleController) GetType() {
	c.TplName = "addType.html"
	c.Layout = "layout.html"
	var articleType []models.ArticleType
	orm.NewOrm().QueryTable("ArticleType").All(&articleType)
	c.Data["articleType"] = articleType
}

func (c *ArticleController) PostType() {
	typeName := c.GetString("typeName")
	if typeName == "" {
		beego.Info("信息不完整，请重新输入")
		c.Redirect("/type", 302)
		return
	}
	o := orm.NewOrm()
	articleType := models.ArticleType{
		TypeName: typeName}
	o.Read(&articleType, "TypeName")
	if articleType.Id > 0 {
		c.Redirect("/type", 302)
		beego.Info("你填写的信息与已有信息重复")
		return
	}
	o.Insert(&articleType)
	c.Redirect("/type", 302)
}

func (c *ArticleController) DeleteType() {
	id, err := c.GetInt("id")
	if err != nil {
		beego.Info("参数传递错误")
	}
	orm.NewOrm().Delete(&models.ArticleType{Id: id})
	c.Redirect("/type", 302)
}
